gtk: Update GtkPointerFocus targets on mapping/sensitivity changes
authorCarlos Garnacho <carlosg@gnome.org>
Fri, 31 Mar 2017 15:49:21 +0000 (17:49 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 25 May 2017 14:25:58 +0000 (16:25 +0200)
Those are situations that must cause foci on these widgets to repick
themselves.

gtk/gtkwidget.c
gtk/gtkwindow.c
gtk/gtkwindowprivate.h

index 915e54e63d55541a04ec5675be8a2fe817876480..96465ca90b65abe743fe598939be0d5326c501d0 100644 (file)
@@ -4448,6 +4448,19 @@ gtk_widget_hide_on_delete (GtkWidget *widget)
   return TRUE;
 }
 
+static void
+update_cursor_on_state_change (GtkWidget *widget)
+{
+  GtkWidget *toplevel;
+
+  toplevel = gtk_widget_get_toplevel (widget);
+  if (!GTK_IS_WINDOW (toplevel))
+    return;
+
+  gtk_window_update_pointer_focus_on_state_change (GTK_WINDOW (toplevel),
+                                                   widget);
+}
+
 /**
  * gtk_widget_map:
  * @widget: a #GtkWidget
@@ -4471,6 +4484,8 @@ gtk_widget_map (GtkWidget *widget)
 
       g_signal_emit (widget, widget_signals[MAP], 0);
 
+      update_cursor_on_state_change (widget);
+
       if (!_gtk_widget_get_has_window (widget))
         gtk_widget_queue_draw (widget);
 
@@ -4501,6 +4516,8 @@ gtk_widget_unmap (GtkWidget *widget)
 
       g_signal_emit (widget, widget_signals[UNMAP], 0);
 
+      update_cursor_on_state_change (widget);
+
       gtk_widget_pop_verify_invariants (widget);
       g_object_unref (widget);
     }
@@ -8405,6 +8422,7 @@ gtk_widget_set_sensitive (GtkWidget *widget,
         }
 
       gtk_widget_propagate_state (widget, &data);
+      update_cursor_on_state_change (widget);
     }
 
   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_SENSITIVE]);
index 7e878897e0f10df8f10c7d8bf9acd4b768209ae7..56082ca74acd7d4d7a2012980b978d464b6836e2 100644 (file)
@@ -11456,3 +11456,31 @@ gtk_window_update_pointer_focus (GtkWindow        *window,
       gtk_window_add_pointer_focus (window, focus);
     }
 }
+
+void
+gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
+                                                 GtkWidget *widget)
+{
+  GList *l = window->priv->foci, *cur;
+
+  while (l)
+    {
+      GtkPointerFocus *focus = l->data;
+
+      cur = l;
+      focus = cur->data;
+      l = cur->next;
+
+      if (GTK_WIDGET (focus->toplevel) == widget)
+        {
+          /* Unmapping the toplevel, remove pointer focus */
+          gtk_window_remove_pointer_focus (window, focus);
+          gtk_pointer_focus_free (focus);
+        }
+      else if (focus->target == widget ||
+               gtk_widget_is_ancestor (focus->target, widget))
+        {
+          gtk_pointer_focus_repick_target (focus);
+        }
+    }
+}
index b8485c72aa28eea40eb8e1b53d9549b7fb472afa..7f62cc7f38a88a23cb1fc9854bdb03b40558c768 100644 (file)
@@ -154,6 +154,9 @@ void             gtk_window_update_pointer_focus (GtkWindow        *window,
                                                   gdouble           x,
                                                   gdouble           y);
 
+void             gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
+                                                                  GtkWidget *widget);
+
 G_END_DECLS
 
 #endif /* __GTK_WINDOW_PRIVATE_H__ */